package com.gict.antifraudback.controller.front.user;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gict.antifraudback.constants.RedisKeyConstants;
import com.gict.antifraudback.entity.User;
import com.gict.antifraudback.exception.BusinessException;
import com.gict.antifraudback.exception.MyException;
import com.gict.antifraudback.redis.RedisService;
import com.gict.antifraudback.result.ResultEnum;
import com.gict.antifraudback.result.ResultView;
import com.gict.antifraudback.service.FilesService;
import com.gict.antifraudback.service.UserService;
import com.gict.antifraudback.utils.DESCode;
import com.gict.antifraudback.utils.UserThreadLocal;
import com.gict.antifraudback.utils.Validator;
import com.gict.antifraudback.vo.MailUtil;
import com.gict.antifraudback.vo.RegisterVo;
import com.gict.antifraudback.vo.UpdatePasswordVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

/**
 * @author ThinkPad
 */
@RestController
@Slf4j
@RequestMapping("/mapi/user")
public class FrontUserController {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private FilesService filesService;


    @GetMapping("/userInfo")
    public ResultView userInfo() {
        return ResultView.ok(UserThreadLocal.get());
    }

    private void verificationCode(String email, String code) {
        String registerKey = String.format(RedisKeyConstants.REGISTER_EMAIL_AUTH_KEY, email);
        String verificationCode = redisService.get(registerKey);
        if (verificationCode == null || !code.equals(verificationCode)) {
            throw new MyException("验证码失效！");
        }
        // 成功删除验证码
        redisService.del(registerKey);
    }

    @PostMapping("/update")
    public ResultView update(@RequestBody User user) {
        User update = userService.getById(UserThreadLocal.get().getId());
        if (update == null) {
            return ResultView.error(ResultEnum.CODE_2, "数据不存在！");
        }
        update.setIntroduction(user.getIntroduction());
        update.setName(user.getName());
        userService.updateById(update);
        return ResultView.ok();
    }

    @PostMapping("/updatePassword")
    public ResultView updatePassword(@RequestBody UpdatePasswordVo updatePasswordVo) {
        this.verificationCode(updatePasswordVo.getEmail(), updatePasswordVo.getVerificationCode());
        User update = userService.getByEmail(updatePasswordVo.getEmail());
        if (update == null) {
            return ResultView.error(ResultEnum.CODE_2, "数据不存在！");
        }
        String password = updatePasswordVo.getPassword();
        if (ObjectUtils.isEmpty(password)) {
            throw new MyException("密码不能为空");
        }
        update.setPassword(DESCode.encode(password));
        userService.updateById(update);
        return ResultView.ok();
    }

    /**
     * 登录后修改密码
     * @param updatePasswordVo
     * @return
     */
    @PostMapping("/loginUpdatePassword")
    public ResultView loginUpdatePassword(@RequestBody UpdatePasswordVo updatePasswordVo) {
        User update = userService.getById(UserThreadLocal.get().getId());
        if (update == null) {
            return ResultView.error(ResultEnum.CODE_2, "数据不存在！");
        }
        String password = updatePasswordVo.getPassword();
        if (ObjectUtils.isEmpty(password)) {
            throw new MyException("密码不能为空");
        }
        update.setPassword(DESCode.encode(password));
        userService.updateById(update);
        return ResultView.ok();
    }

    /**
     * 修改头像
     */
    @PostMapping("/updateAvator")
    public ResultView updateAvator(@RequestParam("image") MultipartFile image) {
        User update = userService.getById(UserThreadLocal.get().getId());
        String url = filesService.uploadFileToOss(image, "avator");
        if (url != null) {
            update.setAvatar(url);
            userService.updateById(update);
            UserThreadLocal.get().setAvatar(url);
            return ResultView.ok(url);
        }
        return ResultView.error(ResultEnum.CODE_2, "上传失败！");
    }

    /**
     * 注册
     *
     * @param registerVo
     * @return
     */
    @PostMapping("/register")
    public ResultView add(@Valid @RequestBody RegisterVo registerVo) {
        this.createBefore(registerVo);
        User user = new User();
        user.setName(registerVo.getName());
        user.setRoles("[\"visitor\"]");// 游客['visitor']
        user.setAbility("[\"READ\",\"WRITE\",\"DELETE\"]");
        user.setEmail(registerVo.getEmail());
        // 设置密码
        user.setPassword(DESCode.encode(registerVo.getPassword()));

        userService.save(user);
        return ResultView.ok();
    }

    /**
     * 创建前检查
     *
     */
    private void createBefore(RegisterVo registerVo) {
        // 此处不校验邮箱格式，获取验证码处校验过了
        // 判断是否存在该账号
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getEmail, registerVo.getEmail());
        User exists = userService.getOne(wrapper);

        if (exists != null) {
            throw new MyException(ResultEnum.CODE_2, "该邮箱已经存在");
        }

        this.verificationCode(registerVo.getEmail(), registerVo.getVerificationCode());
    }

    /**
     * 获取验证码
     *
     * @return
     */
    @GetMapping("/getVerificationCode")
    public ResultView getVerificationCode(@NotBlank @Valid String email) {
        log.info("获取验证码email:{}", email);
        if (Validator.isValidEmail(email)) {
            String title = "邮箱验证码";
            Integer authCode = RandomUtil.randomInt(100000, 999999);
            // 存入redis一分钟过期
            String registerKey = String.format(RedisKeyConstants.REGISTER_EMAIL_AUTH_KEY, email);
            redisService.set(registerKey, String.valueOf(authCode), 60);

            String msg = "你的验证码:" + authCode;
            if (!MailUtil.sendMsg(title, msg, email)) {
                throw new BusinessException("获取验证码失败！");
            }
            return ResultView.ok();
        } else {
            throw new BusinessException("邮箱格式不正确！");
        }
    }


}
